package com.christianposta.learnddd.domain.model.cargo;

import java.util.Date;

import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import com.christianposta.learnddd.domain.model.location.Location;
import com.christianposta.learnddd.domain.shared.AbstractSpecification;
import com.christianposta.learnddd.domain.shared.ValueObject;


public class RouteSpecification extends AbstractSpecification<Itinerary> implements ValueObject<RouteSpecification>{
	
	private Location origin;
	private Location destination;
	private Date arrivalDeadline;
	
	/**
	 * Origin and destination cannot be the same (it would make no sense)
	 * @param origin
	 * @param destination
	 * @param arrivalDeadline
	 */
	public RouteSpecification(final Location origin, final Location destination, final Date arrivalDeadline){
		Validate.notNull(origin, "Origin cannot be null");
		Validate.notNull(destination, "Destination cannot be null");
		Validate.notNull(arrivalDeadline, "Arrival date cannot be null");
		Validate.isTrue(!origin.sameIdentityAs(destination), "Origin cannot be the same place as destination");
		
		this.origin = origin;
		this.destination = destination;
		this.arrivalDeadline = (Date)arrivalDeadline.clone();
	}
	
	public boolean isSatisfiedBy(Itinerary t) {
		return false;
	}
	
	public boolean sameValueAs(RouteSpecification other) {
		return other != null && new EqualsBuilder().append(this.origin, other.origin)
		.append(this.destination, other.destination)
		.append(this.arrivalDeadline, other.arrivalDeadline)
		.isEquals();
	}

	public Location origin(){
		return this.origin;
	}
	
	public Location destination(){
		return this.destination;
	}
	
	public Date arrivalDeadline(){
		return new Date(this.arrivalDeadline.getTime());
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(this.origin)
		.append(this.destination)
		.append(this.arrivalDeadline).toHashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		RouteSpecification other = (RouteSpecification) obj;
		return sameValueAs(other);
	}
	
}
